package org.beian.fmmall.service.Impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.beian.fmmall.VO.ResStatus;
import org.beian.fmmall.VO.ResultVO;
import org.beian.fmmall.beans.IndexImg;
import org.beian.fmmall.dao.IndexImgMapper;
import org.beian.fmmall.service.IndexImgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class IndexImgServiceImpl implements IndexImgService {
    @Autowired
    private IndexImgMapper indexImgMapper;
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private ObjectMapper objectMapper=new ObjectMapper();
    @Override
    public ResultVO listIndexImg() {//双重检测锁，避免缓存击穿问题(redis为null，大量访问数据库)
        List<IndexImg> indexImgs=null;
        try {
            String imgsStr = stringRedisTemplate.boundValueOps("indexImgs").get();//第一次检测
            if(imgsStr!=null){
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, IndexImg.class);
                indexImgs= objectMapper.readValue(imgsStr, javaType);
            }else{
                synchronized (this){
                    String imgsStr2 = stringRedisTemplate.boundValueOps("indexImgs").get();//第二次检测
                    if(imgsStr2==null){
                        System.out.println("正在查询数据库");
                        indexImgs = indexImgMapper.selectIndexImg();
                        if(indexImgs!=null){//避免缓存穿透问题（数据库为null，仍然请求数据库，redis起不到为数据库分担压力）
                            stringRedisTemplate.boundValueOps("indexImgs").set(objectMapper.writeValueAsString(indexImgs));
                            stringRedisTemplate.boundValueOps("indexImgs").expire(1, TimeUnit.DAYS);
                        }else {
                            List<IndexImg> arr=new ArrayList<>();
                            stringRedisTemplate.boundValueOps("indexImgs").set(objectMapper.writeValueAsString(arr));
                            stringRedisTemplate.boundValueOps("indexImgs").expire(10, TimeUnit.SECONDS);
                        }
                    }else{
                        System.out.println("正在第二次查询redis");
                        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, IndexImg.class);
                        indexImgs= objectMapper.readValue(imgsStr2, javaType);
                    }
                }

            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if(indexImgs.size()!=0){
            return new ResultVO(ResStatus.OK,"success",indexImgs);
        }else{
            return new ResultVO(ResStatus.NO,"fail",null);
        }

    }
}
